﻿#include "StdAfx.h"
#ifdef USE_XIMAGE_EFFECT
#include "UIGifAnimEx.h"
#include "../../3rd/CxImage/ximage.h"
//
namespace DuiLib
{
    #define GIFANIMUIEX_EVENT_TIEM_ID    100
    IMPLEMENT_DUICONTROL(CGifAnimExUI)
    struct CGifAnimExUI::Imp
    {
        bool                m_bRealStop            ;//外部停止了
        bool                m_bLoadImg            ;//是否加载过图片
        bool                m_bTimer            ;//是否启动定时器
        bool                m_bAutoStart        ;//是否自动开始
        int                    m_nDelay            ;//循环毫秒数
        UINT                m_nFrameCount        ;//gif图片总帧数
        UINT                m_nFramePosition    ;//当前放到第几帧
        CxImage*            m_pGifImage            ;//gif对象
        CPaintManagerUI*&    m_pManager            ;
        CGifAnimExUI*            m_pOwer                ;//拥有者
        Imp(CPaintManagerUI* & pManager):m_pManager(pManager),
            m_bLoadImg(false),m_bTimer(false),
            m_nDelay(100),m_pGifImage(NULL),m_nFrameCount(0U),
            m_nFramePosition(0U),
            m_pOwer(NULL),m_bRealStop(false),m_bAutoStart(true)
        {
        }
        void SetOwer(CGifAnimExUI *pOwer)
        {
            m_pOwer = pOwer;
        }
        ~Imp()
        {
            if ( m_pGifImage != NULL )
            {
                delete m_pGifImage;
                m_pGifImage = NULL;
            }
        }
        inline void CheckLoadImage()
            {
            if(!m_bLoadImg)
                LoadGifImage();
        }
        inline bool IsLoadImage(){return m_bLoadImg;}
        virtual void LoadGifImage()
        {
            CDuiString sImag = m_pOwer->GetBkImage();
            m_bLoadImg = true;
            m_pGifImage    =    CRenderEngine::LoadGifImageX(STRINGorID(sImag),0, 0);
            if ( NULL == m_pGifImage ) return;
            m_nFrameCount    =    m_pGifImage->GetNumFrames();
            m_nFramePosition = 0;
            m_nDelay = m_pGifImage->GetFrameDelay();
            if (m_nDelay <= 0 ) 
                m_nDelay = 100;
            if(!m_bAutoStart)
                m_bRealStop = true;
            if(m_bAutoStart && m_pOwer->IsVisible())
                StartAnim();
        }
        void SetAutoStart(bool bAuto)
        {
            m_bAutoStart = bAuto;
        }
        void StartAnim()
        {
            if(!m_bTimer)
            {
                if(!IsLoadImage())
                {
                    LoadGifImage();
                    m_pOwer->Invalidate();
                }
                if(m_pGifImage)
                m_pManager->SetTimer( m_pOwer, GIFANIMUIEX_EVENT_TIEM_ID, m_nDelay );
                m_bTimer = true;
            }
        }
        void StopAnim(bool bGoFirstFrame)//bGoFirstFrame 是否跑到第一帧
        {
            if(m_bTimer)
            {
                if(bGoFirstFrame)
                {
                    m_nFramePosition = 0U;
                    m_pOwer->Invalidate();
                }
                m_pManager->KillTimer( m_pOwer, GIFANIMUIEX_EVENT_TIEM_ID );
                m_bTimer = false;
            }
        }
        void EventOnTimer(const WPARAM idEvent )
        {
            if ( idEvent != GIFANIMUIEX_EVENT_TIEM_ID )
                return;
            ++m_nFramePosition;
            if(m_nFramePosition >= m_nFrameCount)
                m_nFramePosition = 0;
            if(!m_pOwer->IsVisible())return;
            m_pOwer->Invalidate();
        }
        void DrawFrame( HDC hDC,const RECT& rcPaint,const RECT &rcItem)
        {
            if ( NULL == hDC || NULL == m_pGifImage ) return;
            if(m_pGifImage)
            {
                if (CxImage* pImage = m_pGifImage->GetFrame(m_nFramePosition))
                    pImage->Draw2(hDC,rcItem);
            }
        }
        void EventSetVisible(bool bVisible)
        {
            if(bVisible)
            {
                if(!m_bRealStop)
                    StartAnim();
            }
            else
                StopAnim(true);
        }
    };
    CGifAnimExUI::CGifAnimExUI(void):m_pImp(new CGifAnimExUI::Imp(m_pManager))
    {
        this;
        m_pImp->SetOwer(this);
    }
    CGifAnimExUI::~CGifAnimExUI(void)
    {
        m_pImp->StopAnim(false);
        delete m_pImp;
        m_pImp = nullptr;
    }
    LPCTSTR CGifAnimExUI::GetClass() const
    {
        return _T("GifAnimUI");
    }
    LPVOID CGifAnimExUI::GetInterface( LPCTSTR pstrName )
    {
            if( _tcscmp(pstrName, _T("GifAnim")) == 0 ) 
                return static_cast<CGifAnimExUI*>(this);
            return CLabelUI::GetInterface(pstrName);
    }
    void CGifAnimExUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
    {
        if( _tcscmp(pstrName, _T("auto")) == 0 ) 
            m_pImp->SetAutoStart(_tcscmp(pstrValue, _T("true")) == 0);
        else
            __super::SetAttribute(pstrName, pstrValue);
    }
    void CGifAnimExUI::Init()
    {
        __super::Init();
        m_pImp->CheckLoadImage();
    }
    void CGifAnimExUI::SetVisible(bool bVisible /*= true*/)
    {
        __super::SetVisible(bVisible);
        m_pImp->EventSetVisible(bVisible);
    }
    void CGifAnimExUI::SetInternVisible(bool bVisible/* = true*/)
    {
        __super::SetInternVisible(bVisible);
        m_pImp->EventSetVisible(bVisible);
    }

    bool CGifAnimExUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl)
    {
        if( !::IntersectRect( &m_rcPaint, &rcPaint, &m_rcItem ) ) return true;
        m_pImp->DrawFrame( hDC,rcPaint,m_rcItem);

        return true;
    }
    void CGifAnimExUI::DoEvent( TEventUI& event )
    {
        this;
        WPARAM nID = event.wParam;
        if( event.Type == UIEVENT_TIMER )
            m_pImp->EventOnTimer(nID);
    }
    void CGifAnimExUI::StartAnim()
    {
        m_pImp->m_bRealStop = false;
        m_pImp->StartAnim();
    }
    void CGifAnimExUI::StopAnim()
    {
        m_pImp->m_bRealStop = true;
        m_pImp->StopAnim(true);
    }
}
#endif//USE_XIMAGE_EFFECT